package com.example.system.service.sysUser.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.core.constants.HttpConstants;
import com.example.common.core.domain.LoginUser;
import com.example.common.core.domain.Result;
import com.example.common.core.domain.vo.LoginUserVO;
import com.example.common.core.enums.Identity;
import com.example.common.core.enums.ResultCode;
import com.example.common.core.exception.ServiceException;
import com.example.common.security.service.TokenService;
import com.example.system.domain.sysUser.SysUser;
import com.example.system.domain.sysUser.dto.LoginDTO;
import com.example.system.domain.sysUser.dto.SysUserSaveDTO;
import com.example.system.mapper.sysUser.SysUserMapper;
import com.example.common.security.utils.BCryptUtils;
import com.example.system.service.sysUser.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;


@Slf4j
@Service
@RefreshScope
public class SysUserService implements ISysUserService {
    @Value("${jwt.secret}")
    private String secret;
    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysUserMapper sysUserMapper;


    @Override
    public String login(LoginDTO loginDTO) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        //根据userAccount从mysql查询用户信息
        SysUser sysUser = sysUserMapper.selectOne(
                queryWrapper
                        .select(SysUser::getUserId,SysUser::getPassword,SysUser::getNickName)
                        .eq(SysUser::getUserAccount, loginDTO.getUserAccount()));
        Result<Void> result = new Result<>();
        //校验用户名和密码
        //用户名不存在
        if (sysUser == null) {
            throw new ServiceException(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        //密码错误
        if (!BCryptUtils.matchsPassword(loginDTO.getPassword(), sysUser.getPassword())) {
            throw new ServiceException(ResultCode.FAILED_LOGIN);
        }
        //密码正确
        //返回令牌给前端
        String token = tokenService.createToken(secret, Identity.ADMIN.getValue(),sysUser.getUserId(),sysUser.getNickName(),null);
        return token;
    }

    //插入新的管理员
    @Override
    public int insertSysUser(SysUserSaveDTO sysUserSaveDTO) {
        //在插入之前，要判断下用户是不是已经存在了，如果存在就抛出业务异常
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserAccount,sysUserSaveDTO.getUserAccount()));
        //判断sysUserList是否为了且数据个数是否为0
        if (CollectionUtil.isNotEmpty(sysUserList)){
            //如果不为空，则抛出一个业务异常
            //自定义的异常
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        //开始真正的插入
        //将dto转为实体
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        return sysUserMapper.insert(sysUser);
    }



    //退出登陆
    @Override
    public boolean logout(String token) {
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteLoginUser(token,secret);
    }


    public Result<LoginUserVO> info(String token) {
        if (StrUtil.isNotEmpty(token) &&
                token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        LoginUser loginUser = tokenService.getLoginUser(token,secret);
        if (loginUser == null){
            return Result.fail();
        }
        log.error(loginUser.toString());
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return Result.ok(loginUserVO);
    }
}
